/*
 * @Author: Starfish_DL
 * @Date: 2020-09-20 14:49:34
 * @LastEditTime: 2020-09-22 12:04:23
 * @LastEditors: Please set LastEditors
 * @Description: Using double linklist to finish homework of 0921.
 * @FilePath: \undefinedc:\vscode\cpp\0920.cpp
 */

#include<iostream>
using namespace std;

class iNodeDouble
{
public:
    iNodeDouble *next;
    iNodeDouble *prior;
    int data;
    iNodeDouble(/* args */);
    ~iNodeDouble();
};

iNodeDouble::iNodeDouble(/* args */)
{
    next=nullptr;
    prior=nullptr;
    data=0;
}

iNodeDouble::~iNodeDouble()
{
}

class iLinkListDouble
{
public:
    iNodeDouble *iL;

    iLinkListDouble(int a[],int n); //CreateList
    ~iLinkListDouble(); //DeleteList
    int getListLength();
    int getElem(int n);
    int locateElem(int e);
    bool isEmpty();
    void insertElem(int n,int e);
    void deleteElem(int n);
    void dispList();
};
/*
iLinkListDouble::iLinkListDouble(int a[],int n)
{
    iL=new iNodeDouble();
    for (int i = 0; i < n; i++)
    {
        iNodeDouble *s=new iNodeDouble();
        s->data=a[i];
        s->next=iL->next;
        if (iL->next!=nullptr)
        {
            iL->next->prior=s;
        }
        iL->next=s;
        s->prior=iL;
    }
    
}*/

iLinkListDouble::iLinkListDouble(int a[],int n)
{
    iL=new iNodeDouble();
    iNodeDouble *p=iL;
    for (int i = 0; i < n; i++)
    {
        iNodeDouble *s=new iNodeDouble();
        s->data=a[i];
        p->next=s;
        s->prior=p;
        p=s;
    }
}

iLinkListDouble::~iLinkListDouble()
{
    iNodeDouble *pre=iL->next,*p=iL;
    while (pre!=nullptr)
    {
        delete p;
        p=pre;
        pre=pre->next;
    }
    delete p;
}

void iLinkListDouble::dispList()
{
    /**
     * @description: display all elements in this linklist.
     * @param {null} 
     * @return {void} 
     */
    iNodeDouble *p=iL->next;
    while (p!=nullptr)
    {
        cout<<p->data<<" ";
        p=p->next;
    }
}

void iLinkListDouble::deleteElem(int n)
{
    /**
     * @description: delete position n of the linklist.
     * @param {int number} 
     * @return {void} 
     */
    if (n<=0)
    {
        return;
    }
    iNodeDouble *p=iL;
    for (int i = 0; i < n-1; i++)
    {
        p=p->next;
        if (p==nullptr)
        {
            return;
        }
    }
    p->next=p->next->next;
    delete p->next->prior;
    p->next->prior=p;
}

void iLinkListDouble::insertElem(int n,int e)
{
    /**
     * @description: insert the parameter e into the 
     * position n in the linklist.
     * @param {int number,int element} 
     * @return {void} 
     */
    if (n<=0)
    {
        return;
    }
    iNodeDouble *p=iL;
    for (int i = 0; i < n-1; i++)
    {
        p=p->next;
        if (p==nullptr)
        {
            return;
        }
    }
    iNodeDouble *s=new iNodeDouble();
    s->data=e;
    s->next=p->next;
    s->prior=p;
    p->next->prior=s;
    p->next=s;
}

int iLinkListDouble::getListLength()
{
    /**
     * @description: get length of the linklist.
     * @param {null} 
     * @return {int} 
     */
    iNodeDouble *p=iL;
    int k=0;
    while (p->next!=nullptr)
    {
        p=p->next;
        k++;
    }
    return k;
}

int iLinkListDouble::getElem(int n)
{
    /**
     * @description: get the data of linklist[n],
     * if the execution of this function is wrong,return NULL.
     * @param {int number} 
     * @return {int} 
     */
    if (n<=0)
    {
        return NULL;
    }
    iNodeDouble *p=iL;
    for (int i = 0; i < n; i++)
    {
        p=p->next;
        if (p->next==nullptr)
        {
            return NULL;
        }
    }
    return (p->data);
}

int iLinkListDouble::locateElem(int e)
{
    /**
     * @description: return the location of the param e
     * in the linklist.
     * @param {int element} 
     * @return {int} 
     */
    iNodeDouble *p=iL;
    int k=0;
    while (p!=nullptr)
    {
        p=p->next;
        k++;
        if (e==p->data)
        {
            return k;
        }
    }
    return NULL;
}

int main(int argc, const char** argv) 
{
    int a[6]={1,2,3,4,5,6};
    iLinkListDouble *link1=new iLinkListDouble(a,6);
    link1->deleteElem(4);
    link1->insertElem(4,9);
    link1->dispList();
    delete link1;
    return 0;
}